#include <iostream>

using std::cout;
using std::endl;

class Point
{
public:
    Point(int ix = 0, int iy = 0)
    : _ix(ix)
    , _iy(iy)
    {
        cout << "Point(int = 0, int = 0)" << endl;
    }

    //默认情况下，编译器会自动生成拷贝构造函数
    Point(const Point &rhs)
    : _ix(rhs._ix)
    , _iy(rhs._iy)
    {
        cout << "Point(const Point &)" << endl;
    }

    //默认情况下，编译器也会自动生成赋值运算符函数
    //1、参数中的引用符号可以去掉吗？
    //答案：如果去掉会多执行一次拷贝构造函数，多增加开销，降低
    //执行效率
    //
    //2、参数中的const可以去掉吗？
    //答案：如果赋值运算符函数的右操作是右值，又会出现非const
    //左值引用不能绑定右值的问题
    //
    //3、返回类型一定要用引用？
    //答案：会满足拷贝构造函数的调用时机3，函数的返回类型是类类型
    //的时候，在执行return语句的时候，会指向拷贝构造函数，也会
    //增加函数的调用开销
    //
    //4、返回类型一定要使用类类型（对象）吗？void
    //答案：如果不是类类型，那么不能解决连等的问题
    //pt3 = pt2 = pt
    /* void operator=(const Point &rhs) */
    Point &operator=(const Point &rhs)
    {
        cout << "Point &operator=(const Point &)" << endl;
        this->_ix = rhs._ix;//赋值
        this->_iy = rhs._iy;

        return *this;//返回对象本身
    }

    void print()
    {
        cout << "(" << _ix
             << ", " << _iy
             << ")" << endl;
    }

    //默认情况下，编译器也会自动生成析构函数
    ~Point()
    {
        cout << "~Point()" << endl;
    }

private:
    int _ix;
    int _iy;
};

void test()
{
    int a = 10;
    int b = 20;
    int c = 30;
    c = b = a;
    cout <<"a = " << a 
         << ", b = " << b 
         << ", c = " << c
         << endl << endl;

    Point pt(1, 2);//pt栈对象
    cout << "pt = ";
    pt.print();

    cout << endl;
    /* Point pt2 = pt; */
    Point pt2(3, 4);//pt2也是栈对象
    cout << "pt2 = ";
    pt2.print();

    cout << endl;
    //赋值运算符函数
    /* pt2 = pt;// */
    pt2.operator=(pt);
    cout << "pt = ";
    pt.print();
    cout << "pt2 = ";
    pt2.print();

    cout << endl;
    pt2 = Point(1, 2);

    cout << endl << endl;
    Point pt3(30, 50);
    cout << "pt3 = ";
    pt3.print();

    cout << endl << endl;
    pt3 = pt2 = pt;//Point  = void
    pt3.operator=(pt2.operator=(pt));
}


int main(int argc, char *argv[])
{
    test();
    return 0;
}

